package handlers

import (
	"errors"
	"strconv"
	"time"

	"sales-web/server/dal"

	"github.com/gin-gonic/gin"
)

func (h *Handler) QueryUsers(c *gin.Context) {
	var result []dal.User
	var count int64
	err := h.dbc.Model(&dal.User{}).Find(&result).Count(&count).Error

	// err = h.dbc.Debug().Find(result).Error
	if err != nil {
		SendErrResp(c, 500, err)
		return
	}
	SendOkResp(c, result)
}

func (h *Handler) UserLogin(c *gin.Context) {
	var request struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}
	err := c.BindJSON(&request)
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	var user dal.User
	err = h.dbc.Model(&dal.User{}).
		Where("username =? and password =?", request.Username, request.Password).
		First(&user).Error
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	user.Password = ""
	expireTime := time.Now().Add(time.Hour * 24)
	expireAt := expireTime.Unix()
	jwtInfo := &UserJwtInfo{
		ID:        user.ID,
		Username:  user.Username,
		Nickname:  user.Nickname,
		Email:     user.Email,
		Role:      user.Role,
		CreatedAt: user.CreatedAt,
	}
	token, err := CreateUserJwt(jwtInfo, expireAt)
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	c.SetCookie(JwtCookieName, token, 3600*24, "/", "", false, true)
	SendOkResp(c, user)
}

func (h *Handler) CurrentUser(c *gin.Context) {
	user := GetCurrentUser(c)
	SendOkResp(c, user)
}

func (h *Handler) UserLogout(c *gin.Context) {
	c.SetCookie(JwtCookieName, "", -1, "/", "", false, true)
	SendOkResp(c, "")
}

func (h *Handler) CreateUser(c *gin.Context) {
	var user dal.User
	err := c.BindJSON(&user)
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	if user.Username == "" || user.Password == "" || user.Role == "" {
		SendErrResp(c, 400, errors.New("invalid input"))
		return
	}
	var count int64
	err = h.dbc.Model(&dal.User{}).Where("username = ?", user.Username).Count(&count).Error
	if err != nil {
		SendErrResp(c, 500, err)
		return
	}
	if count > 0 {
		SendErrResp(c, 400, errors.New("username exist"))
		return
	}
	err = h.dbc.Create(&user).Error
	if err != nil {
		SendErrResp(c, 500, err)
		return
	}
	SendOkResp(c, user)
}

func (h *Handler) DeleteUser(c *gin.Context) {
	idStr, _ := c.Params.Get("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	var user dal.User
	err = h.dbc.Model(&dal.User{}).Where("id= ?", id).First(&user).Error
	if err != nil {
		SendErrResp(c, 500, err)
		return
	}
	err = h.dbc.Delete(&user).Error
	if err != nil {
		SendErrResp(c, 500, err)
		return
	}

	SendOkResp(c, "")
}

func (h *Handler) UpdateUser(c *gin.Context) {
	idStr, _ := c.Params.Get("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	var request struct {
		Nickname string `json:"nickname"`
		Password string `json:"password"`
		Email    string `json:"email"`
		Role     string `json:"role"`
	}
	err = c.BindJSON(&request)
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	var user dal.User
	err = h.dbc.Model(&dal.User{}).Where("id= ?", id).First(&user).Error
	if err != nil {
		SendErrResp(c, 400, err)
		return
	}
	user.Nickname = request.Nickname
	user.Email = request.Email
	user.Role = request.Role
	if request.Password != "" {
		user.Password = request.Password
	}
	err = h.dbc.Save(&user).Error
	if err != nil {
		SendErrResp(c, 500, err)
		return
	}
	SendOkResp(c, "")
}
